From ea0dc295685f416f54b920dceb1016b550b34473 Mon Sep 17 00:00:00 2001 From: Debian Qt/KDE Maintainers Date: Wed, 31 Dec 2025 13:28:57 +0300 Subject: [PATCH] QReadWriteLock: fix data race on the d_ptr members Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit?id=80d01c4ccb697b9d Last-Update: 2025-12-14 The loadRelaxed() at the beginning of tryLockForRead/tryLockForWrite isn't enough to bring us the non-atomic write of the recursive bool. Same issue with the std::mutex itself. Gbp-Pq: Name qreadwritelock_data_race.diff --- src/corelib/thread/qreadwritelock.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/corelib/thread/qreadwritelock.cpp b/src/corelib/thread/qreadwritelock.cpp index 9dd850311..84d73444b 100644 --- a/src/corelib/thread/qreadwritelock.cpp +++ b/src/corelib/thread/qreadwritelock.cpp @@ -258,7 +258,10 @@ bool QReadWriteLock::tryLockForRead(int timeout) d = val; } Q_ASSERT(!isUncontendedLocked(d)); - // d is an actual pointer; + // d is an actual pointer; acquire its contents + d = d_ptr.loadAcquire(); + if (!d || isUncontendedLocked(d)) + continue; if (d->recursive) return d->recursiveLockForRead(timeout); @@ -365,7 +368,10 @@ bool QReadWriteLock::tryLockForWrite(int timeout) d = val; } Q_ASSERT(!isUncontendedLocked(d)); - // d is an actual pointer; + // d is an actual pointer; acquire its contents + d = d_ptr.loadAcquire(); + if (!d || isUncontendedLocked(d)) + continue; if (d->recursive) return d->recursiveLockForWrite(timeout); -- 2.30.2